local fmt = function(seconds)
  local mm = math.floor(seconds / 60)
  local ss = seconds - mm * 60
  local hh = math.floor(mm / 60)
  mm = mm - hh * 60

  return (hh < 10 and '0' .. hh or '' .. hh) ..
      ':' .. (mm < 10 and '0' .. mm or '' .. mm) .. ':' .. (ss < 10 and '0' .. ss or '' .. ss)
end
local font = GameFontNormal:GetFont()

local frame = CreateFrame("Frame", "InstanceTimerTimerFrame", InstanceTimerFrame)
frame:SetWidth(100)
frame:SetHeight(InstanceTimer.height)
InstanceTimer.timer = frame
InstanceTimer.addFrame(frame)
frame.timesleftText = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
frame.timesleftText:SetAllPoints(frame)
frame.timesleftText:SetFont(font, InstanceTimer.fontsize1)
frame.timesleftText:SetJustifyH("CENTER")

-- frame:RegisterEvent("PLAYER_ENTERING_WORLD")
-- frame:RegisterEvent("COMBAT_LOG_EVENT")
-- frame:SetScript("OnEvent", function() end)

local clickArea = CreateFrame("Button", "InstanceTimerTimerButton", frame)
clickArea:SetPoint("CENTER", frame, "CENTER")
clickArea:SetWidth(20)
clickArea:SetHeight(24)
-- clickArea:RegisterForClicks("LeftButtonUp")
clickArea:SetScript("OnMouseDown", function()
  if arg1 == "LeftButton" then
    -- 左键暂停 / 继续
    if InstanceTimerDB.timer.stat == 1 then
      frame.pause()
    else
      frame.start()
    end
  elseif arg1 == "RightButton" then
    -- 右键归零停止
    frame.stop(true)
  elseif arg1 == "MiddleButton" then
    -- 中键打开面板
    if InstanceTimer.loaded and InstanceTimer.config then
      InstanceTimer.config.toggle()
    end
  end
end)

local colors = {
  { 0.8, 0.8, 0.8, 1 },
  { 0,   0.8, 0,   1 },
  { 0.8, 0.8, 0,   1 },
}

local defaults = {
  timertime = 0,
  pausedoffset = 0,
  autostart = true,
  autoreset = true,
  autostop = true,
  autoresetout = true,
  autopausenames = {},
  stat = 0,
  hidenotininstance = false,
}

frame.onLoad = function()
  if not InstanceTimerDB.timer then
    InstanceTimerDB.timer = {}
  end
  for k, v in pairs(defaults) do
    if InstanceTimerDB.timer[k] == nil then
      InstanceTimerDB.timer[k] = v
    end
  end

  frame.timesleftText:SetText(fmt(InstanceTimerDB.timer.timertime or 0))
  frame.timesleftText:SetTextColor(unpack(colors[InstanceTimerDB.timer.stat + 1]))

  if InstanceTimerDB.timer.stat == 1 then
    frame.start()
  end
end

local tick = function()
  if InstanceTimerDB.timer.stat ~= 1 then return end
  if not InstanceTimerDB.timer.lasttime then return end
  local tt = time()
  if tt > InstanceTimerDB.timer.lasttime then
    InstanceTimerDB.timer.timertime = tt - InstanceTimerDB.timer.starttime + InstanceTimerDB.timer.pausedoffset
    frame.timesleftText:SetText(fmt(InstanceTimerDB.timer.timertime))
    InstanceTimerDB.timer.lasttime = tt
  end
end

local start = function(reset)
  if reset then
    InstanceTimerDB.timer.timertime = 0
    InstanceTimerDB.timer.pausedoffset = 0
  end
  if InstanceTimerDB.timer.starttime == nil or reset == true or InstanceTimerDB.timer.stat == 0 or InstanceTimerDB.timer.stat == 2 then
    InstanceTimerDB.timer.starttime = time()
    InstanceTimerDB.timer.lasttime = InstanceTimerDB.timer.starttime
  end
  InstanceTimerDB.timer.stat = 1
  frame.timesleftText:SetTextColor(unpack(colors[InstanceTimerDB.timer.stat + 1]))
  frame:SetScript("OnUpdate", tick)
end

local pause = function()
  if not InstanceTimerDB.timer.stat or InstanceTimerDB.timer.stat ~= 1 then
    return
  end
  InstanceTimerDB.timer.stat = 2
  InstanceTimerDB.timer.pausedoffset = InstanceTimerDB.timer.timertime
  frame.timesleftText:SetTextColor(unpack(colors[InstanceTimerDB.timer.stat + 1]))
  frame:SetScript("OnUpdate", nil)
end

local stop = function(reset)
  InstanceTimerDB.timer.stat = 0
  frame:SetScript("OnUpdate", nil)
  frame.timesleftText:SetTextColor(unpack(colors[InstanceTimerDB.timer.stat + 1]))
  if reset then
    InstanceTimerDB.timer.timertime = 0
    InstanceTimerDB.timer.pausedoffset = 0
    frame.timesleftText:SetText(fmt(0))
  end
end

InstanceTimer.register('IN_INSTANCE', frame)
frame.IN_INSTANCE = function()
  frame.updateVisible(true)
  if InstanceTimerDB.timer.autoreset then
    InstanceTimerDB.timer.timertime = 0
    InstanceTimerDB.timer.pausedoffset = 0
    InstanceTimerDB.timer.starttime = time()
    InstanceTimerDB.timer.lasttime = InstanceTimerDB.timer.starttime
    frame.timesleftText:SetText(fmt(0))
  end
  if InstanceTimerDB.timer.autostart then
    frame.start()
  end
end

InstanceTimer.register('OUT_INSTANCE', frame)
frame.OUT_INSTANCE = function()
  frame.updateVisible(true)
  if InstanceTimerDB.timer.autoresetout then
    InstanceTimerDB.timer.timertime = 0
    InstanceTimerDB.timer.pausedoffset = 0
    InstanceTimerDB.timer.starttime = time()
    InstanceTimerDB.timer.lasttime = InstanceTimerDB.timer.starttime
    frame.timesleftText:SetText(fmt(0))
  end
  if InstanceTimerDB.timer.autostop then
    frame.stop(true)
  end
end

local updateVisible = function(updateFrameSize)
  if frame:IsVisible() and (not InstanceTimerDB.showtimer or (InstanceTimerDB.timer.hidenotininstance == true and not InstanceTimer.boomcounter.inInstance(true))) then
    frame:Hide()
    if updateFrameSize then InstanceTimerFrame.updateFramesWidthAndPoint() end
  elseif not frame:IsVisible() and InstanceTimerDB.showtimer and (not InstanceTimerDB.timer.hidenotininstance or InstanceTimer.boomcounter.inInstance(true)) then
    frame:Show()
    if updateFrameSize then InstanceTimerFrame.updateFramesWidthAndPoint() end
  end
end
frame.updateVisible = updateVisible

InstanceTimer.register("OPTIONS_CHANGED", frame)
frame.OPTIONS_CHANGED = function(key, value)
  if key == "showtimer" or key == "timer.hidenotininstance" then
    -- if value then
    --   frame:Show()
    -- else
    --   frame:Hide()
    -- end
    updateVisible(true)
  end
end

frame.start = start
frame.pause = pause
frame.stop = stop
frame.buttons = { clickArea }

frame.toggle = function()
  if InstanceTimerDB.timer.stat == 1 then
    -- print("已暂停计时")
    pause()
  else
    -- print("开始计时")
    start()
  end
end
